package com.weguard.websocket;

import java.io.IOException;
import java.util.HashMap;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import net.sf.json.JSONObject;

/**
 * 连接到服务器的url
 * http://localhost:8080/FiveInRow/myhtml/chess.html
 * */

@ServerEndpoint(value="/webSever") 
public class WebSocket {
  //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
  public static HashMap<Integer,WebSocket> webSocketMap = new HashMap<Integer,WebSocket>();
  public static HashMap<Integer,Boolean> waitQueue = new HashMap<Integer,Boolean>();
  //与某个客户端的连接会话，需要通过它来给客户端发送数据
  public Session session;
  
  public static int ID = 0;
  public static int count = 0;
  public int myid = 0;
  public int opponentid = 0;
  public String name = null;
  /**
   * 连接建立成功调用的方法
   * @param session  可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
   */
  @OnOpen
  public void onOpen( Session session){
      this.session = session;
      ID++;
      count++;
      this.name = "unamed";
      this.myid = ID;
      webSocketMap.put(myid, this);     //加入map中
      waitQueue.put(myid,false);   //加入queue中，false表示没有在比赛中
  }
   
  public void onMatch() {
	  boolean find = false;
	  try {
    	  Result result = new Result();
    	  for(Integer id :waitQueue.keySet()) {
    		  if(id!=this.myid && !waitQueue.get(id)){  //找到空闲玩家
    			  WebSocket opponent_socket = webSocketMap.get(id);
    			  waitQueue.put(id,true);
    			  waitQueue.put(this.myid,true);
    			  this.opponentid = opponent_socket.myid;
    			  opponent_socket.opponentid = this.myid;
    			  result.setMsgtype("start");
    			  result.setColor("black");
    			  result.setMessage("匹配成功！游戏开始：\n现在是你的回合！\n");
    			  result.setPermit(true);
    			  result.setUsrname("你：" + this.name + "  vs  " + "对手:"+opponent_socket.name);
    			  System.out.print(JSONObject.fromObject(result).toString());
    			  sendMessage(JSONObject.fromObject(result).toString());
    			  result.setMsgtype("start");
    			  result.setColor("white");
    			  result.setMessage("匹配成功！游戏开始：\n现在是对手的回合！\n");
    			  result.setPermit(false);
    			  result.setUsrname("你：" + opponent_socket.name + "  vs  " + "对手:"+this.name);
    			  opponent_socket.sendMessage(JSONObject.fromObject(result).toString()); 
    			  System.out.print(JSONObject.fromObject(result).toString());
    			  find = true;
    		  }
    	 }
    	 if(!find) { 
    		 result.setMsgtype("wait");
    		 result.setMessage("正在等待玩家...\n");
    		 sendMessage(JSONObject.fromObject(result).toString());	
    	 }
	  } catch (Exception e) {
			e.printStackTrace();
	  }
  }
  /**
   * 连接关闭调用的方法
 * @throws IOException 
   */
  @OnClose
  public void onClose(){
      webSocketMap.remove(myid);  //从set中删除
      waitQueue.remove(myid);
      count--;
      try {
    	  WebSocket socket = null;
          socket = webSocketMap.get(this.opponentid);
    	  if(socket!=null){
    		  Result result = new Result();
    		  result.setMsgtype("opponentquit");
    		  result.setMessage("你的对手已离开！重新寻找玩家。\n");
    		  socket.sendMessage(JSONObject.fromObject(result).toString());
    		  socket.opponentid = 0;
    		  waitQueue.put(socket.myid, false);
    	  }
	} catch (Exception e) {
		e.printStackTrace();
	}
  }
  /**
   * 收到客户端消息后调用的方法
   * @param message 客户端发送过来的消息
   * @param session 可选的参数
   */
  @OnMessage
  public void onMessage(String message) {
	  System.out.println(message);
	  JSONObject json = JSONObject.fromObject(message);
	  Result result = (Result) JSONObject.toBean(json,Result.class);
     try { 
	      if(result.getMsgtype().equals("username")) {
	    	  this.name = result.getMessage();
	    	  onMatch();
	      }else if(result.getMsgtype().equals("play")){
	    	  WebSocket s = webSocketMap.get(this.opponentid);
	    	  s.sendMessage(JSONObject.fromObject(result).toString());  
	      }else if(result.getMsgtype().equals("end")) {
	    	  this.opponentid = 0;
	    	  waitQueue.put(myid, false);
	    	  onMatch();
	      }
     }catch(Exception e){
			e.printStackTrace();
     }
}
 
   
  /**
   * 发生错误时调用
   * @param session
   * @param error
   */
  @OnError
  public void onError(Session session, Throwable error){
      System.out.println("连接断开");
//      error.printStackTrace();
  }
  
  public void sendMessage(String message) throws IOException{
      this.session.getBasicRemote().sendText(message);
      //this.session.getAsyncRemote().sendText(message);
  }
}
